home *** CD-ROM | disk | FTP | other *** search
- UNIT Hercules;
- INTERFACE
-
- {***************************************************************************}
- TYPE Bob=OBJECT { Bob object }
- Xl,Yl,Bc:BYTE; { Length, Height , backgroundcolor }
- Fg,Bg:ARRAY[0..63,0..63] OF BYTE;{ Foreground and background array }
- PROCEDURE GetFg(X,Y:WORD); { Get Fg array }
- PROCEDURE SetFg(X,Y:WORD); { Set Fg array }
- PROCEDURE GetBg(X,Y:WORD); { Get Bg array }
- PROCEDURE SetBg(X,Y:WORD); { Set Bg array }
- END; { }
- {***************************************************************************}
- CONST Text =033; {00100001} { Since both Text and Graphics uses }
- Graphic =003; {00000011} { the same memory area you have to }
- {***************************************************************************}
- VAR Page , { be careful when using routines }
- Mode :BYTE; { that writes 'text' to the screen }
- MaxX , { then in graphics mode, one of }
- MaxY :WORD; { these functions is READLN(); !!! }
- Fh :BYTE; { Fontheight }
- {***************************************************************************}
- PROCEDURE SetMode(Md:BYTE); { Set either text or graph. Page 0 }
- PROCEDURE SetPix(X,Y:WORD; P:BYTE); { Sets pixel on Page, P=0,1,2 }
- FUNCTION GetPix(X,Y:WORD):BYTE; { Returns pixel color in Page (0/1) }
- PROCEDURE Clear(P:BYTE); { Clears/Sets the whole Page }
- PROCEDURE ChangePage; { Switches Page }
- {***************************************************************************}
- PROCEDURE ClearBoth(M:BYTE); { Clears both pages }
- PROCEDURE Hline(Xa,Xb,Y:WORD; Color:BYTE); { Horizontal line }
- PROCEDURE Vline(X,Ya,Yb:WORD; Color:BYTE); { Vertical line }
- PROCEDURE Box(Xa,Ya,Xb,Yb:WORD; Color:BYTE); { Draws a rectangle }
- PROCEDURE Fbox(Xa,Ya,Xb,Yb:WORD; Color:BYTE); { Draws a filled rectangle }
- PROCEDURE Line(X1,Y1,X2,Y2:INTEGER; Col:BYTE); { Draws any line }
- {***************************************************************************}
- FUNCTION UseFont(Ptr:POINTER):POINTER; { UseFont(@Proc/Pointer) }
- PROCEDURE PlotChar(X,Y:INTEGER; Ch:BYTE; Color,Bg:BYTE); { Plots CHAR expl. }
- PROCEDURE DrawChar(X,Y:INTEGER; Ch:BYTE; Color:BYTE); { Plots CHAR only }
- PROCEDURE WriteLine(X,Y:INTEGER; S:STRING; C,B:BYTE); { C=B->Draw / Plot }
- {***************************************************************************}
-
- IMPLEMENTATION
-
- VAR A,B:BYTE;
- CONST CrtReg=$03B4;
- CrtCnt=$03B8;
- CrtCnf=$03BF;
- VideoS=$B000;
-
- PROCEDURE SetMode(Md:BYTE); ASSEMBLER;
- ASM
- MOV DX,CrtCnt { Enable the Mode, but turn off the }
- MOV AL,Md { screen, for modechange. }
- OUT DX,AX
- MOV DX,CrtReg
- CMP AL,Text { Is it text or graphics mode? }
- JE @Text
- MOV AX,$3500; OUT DX,AX { Enable Special CRT graphics mode. }
- MOV AX,$2D01; OUT DX,AX
- MOV AX,$2E02; OUT DX,AX
- MOV AX,$0703; OUT DX,AX
- MOV AX,$5B04; OUT DX,AX
- MOV AX,$0205; OUT DX,AX
- MOV AX,$5706; OUT DX,AX
- MOV AX,$5707; OUT DX,AX
- MOV AX,$0208; OUT DX,AX
- MOV AX,$0309; OUT DX,AX
- MOV AX,$000A; OUT DX,AX
- MOV AX,$000B; OUT DX,AX
- MOV MaxX,719 { Report Max resolution. }
- MOV MaxY,347
- JMP @Next
- @Text: MOV AX,$6100; OUT DX,AX { Enable special CRT text mode. }
- MOV AX,$5001; OUT DX,AX
- MOV AX,$5202; OUT DX,AX
- MOV AX,$0F03; OUT DX,AX
- MOV AX,$1904; OUT DX,AX
- MOV AX,$0605; OUT DX,AX
- MOV AX,$1906; OUT DX,AX
- MOV AX,$1907; OUT DX,AX
- MOV AX,$0208; OUT DX,AX
- MOV AX,$0D09; OUT DX,AX
- MOV AX,$0B0A; OUT DX,AX
- MOV AX,$0C0B; OUT DX,AX
- MOV MaxX,79 { Report max resolution. }
- MOV MaxY,24
- @Next: MOV DX,CrtCnt { Now enable this mode and turn the }
- MOV AL,Md { screen back on. }
- OR AL,00001000b
- OUT DX,AL
- MOV Page,0 { Save both mode and page number. }
- MOV Mode,AL
- END;
-
- PROCEDURE SetPix(X,Y:WORD; P:BYTE); ASSEMBLER;
- ASM
- MOV BX,X { Save X in BX }
- MOV DX,Y { Save Y in DX }
- CMP BX,MaxX { Is X>MaxX ? }
- JG @Ende { Yes, end this procedure }
- CMP DX,MaxY { No , Is Y>MaxY ? }
- JG @Ende { Yes, end this procedure }
- XOR DI,DI { No ,Clear DI }
- MOV CX,VideoS { CX=Basic Video Segment address }
- CMP Page,0 { Is current page Page 0 ? }
- JE @Next { Yes, Do not add anything to Seg. }
- ADD CX,$0800 { No , Add $800 to get Page 1 }
- @Next: MOV ES,CX { Save This segment in ExtraSement }
- MOV AX,DX { AX=Y }
- SHR AX,2 { Divide AX by four }
- MOV CL,90 { Prepare multiplication }
- MUL CL { Multiply line by 90 }
- AND DX,00000011b { remove anything but b0,1 in DX (Y)}
- ROR DX,3 { Shift DX by 3 }
- MOV DI,BX { DI = X value }
- SHR DI,3 { Divide DI by 8 }
- ADD DI,AX { + 90 * INT( Line DIV 4 ) }
- ADD DI,DX { + $2000 * ( Line MOD 4 ) }
- MOV CL,7 { Maximum of 7 moves }
- AND BX,7 { Column MOD 8 }
- SUB CL,BL { 7 - Column MOD 8 }
- MOV AH,1 { Prepare to determine bit position }
- SHL AH,CL { Determine bit position }
- MOV AL,ES:[DI] { Get byte value of bitposition }
- CMP P,1
- JNE @Nxt1
- OR AL,AH
- JMP @End1
- @Nxt1: CMP P,0
- JNE @Nxt2
- NOT AH
- AND AL,AH
- JMP @End1
- @Nxt2: XOR AL,AH
- @End1: MOV ES:[DI],AL
- @Ende:
- END;
-
- FUNCTION GetPix(X,Y:WORD):BYTE; ASSEMBLER;
- ASM
- MOV BX,X { Save X in BX }
- MOV DX,Y { Save Y in DX }
- CMP BX,MaxX { Is X>MaxX ? }
- JG @Ende { Yes, end this procedure }
- CMP DX,MaxY { No , Is Y>MaxY ? }
- JG @Ende { Yes, end this procedure }
- XOR DI,DI { No ,Clear DI }
- MOV CX,VideoS { CX=Basic Video Segment address }
- CMP Page,0 { Is current page Page 0 ? }
- JE @Next { Yes, Do not add anything to Seg. }
- ADD CX,$0800 { No , Add $800 to get Page 1 }
- @Next: MOV ES,CX { Save This segment in ExtraSement }
- MOV AX,DX { AX=Y }
- SHR AX,2 { Divide AX by four }
- MOV CL,90 { Prepare multiplication }
- MUL CL { Multiply line by 90 }
- AND DX,11 { remove anything but b0,1 in DX (Y)}
- ROR DX,3 { Shift DX by 3 }
- MOV DI,BX { DI = X value }
- SHR DI,3 { Divide DI by 8 }
- ADD DI,AX { + 90 * INT( Line DIV 4 ) }
- ADD DI,DX { + $2000 * ( Line MOD 4 ) }
- MOV CL,7 { Maximum of 7 moves }
- AND BX,7 { Column MOD 8 }
- SUB CL,BL { 7 - Column MOD 8 }
- MOV AH,1 { Prepare to determine bit position }
- SHL AH,CL { Determine bit position }
- MOV AL,ES:[DI] { Get byte value of bitposition }
- NOT AH { Make bitmask }
- AND AL,AH { Use mask on bytevalue }
- CMP AL,0 { Is AL = 0 (bit is blank) }
- JE @Ende { Yes, Return 0 }
- MOV AL,1 { No , Return 1 }
- @Ende:
- END;
-
- PROCEDURE Clear(P:BYTE); ASSEMBLER;
- ASM
- MOV AX,$0700
- MOV CX,$2000
- MOV BL,Mode
- AND BL,00100011b
- CMP BL,Text
- JE @Next
- MOV CX,$4000 { CX = $4000 one whole graphic page }
- MOV AX,0 { Prepare to clear graphics }
- CMP P,0 { Is P=0 ? }
- JE @Next { Yes, keep current AX }
- MOV AX,$FFFF { No , Prepare to set whole screen }
- @Next: XOR DI,DI { DI = 0 }
- MOV CX,$4000 { CX = $4000 one whole graphic page }
- MOV BX,VideoS { BX = Basic Video segment address }
- CMP Page,0 { Is this page 0 ? }
- JE @Nxt2 { Yes, prepare to execute }
- ADD BX,$0800 { No , prepare page 1 }
- @Nxt2: MOV ES,BX { ES = This video segment }
- REP STOSW { REPEAT clear/set op. until CX=0 }
- END;
-
- PROCEDURE ChangePage; ASSEMBLER;
- ASM
- MOV AL,Mode
- MOV DX,CrtCnt
- XOR AL,10000000b; OUT DX,AL
- MOV Mode,AL
- INC Page
- CMP Page,1
- JE @Ende
- MOV Page,0
- @Ende:
- END;
-
- {***************************************************************************}
-
- PROCEDURE ClearBoth(M:BYTE);
- BEGIN
- ChangePage; Clear(0);
- ChangePage; Clear(0);
- END;
-
- PROCEDURE Hline(Xa,Xb,Y:WORD; Color:BYTE);
- BEGIN
- FOR Xa:=Xa TO Xb DO SetPix(Xa,Y,Color);
- END;
-
- PROCEDURE Vline(X,Ya,Yb:WORD; Color:BYTE);
- BEGIN
- FOR Ya:=Ya TO Yb DO SetPix(X,Ya,Color);
- END;
-
- PROCEDURE Box(Xa,Ya,Xb,Yb:WORD; Color:BYTE);
- BEGIN
- Hline(Xa,Xb,Ya,Color); Hline(Xa,Xb,Yb,Color);
- Vline(Xa,Ya,Yb,Color); Vline(Xb,Ya,Yb,Color);
- END;
-
- PROCEDURE Fbox(Xa,Ya,Xb,Yb:WORD; Color:BYTE);
- BEGIN
- IF ABS(Xb-Xa)<ABS(Yb-Ya) THEN FOR Xa:=Xa TO Xb DO Vline(Xa,Ya,Yb,Color)
- ELSE FOR Ya:=Ya TO Yb DO Hline(Xa,Xb,Ya,Color);
- END;
-
- PROCEDURE Line(X1,Y1,X2,Y2:INTEGER; Col:BYTE);
- VAR D,Dx,Dy,Ai,Bi,Xi,Yi,X,Y:INTEGER;
- BEGIN
- IF (ABS(X2-X1)<ABS(Y2-Y1)) THEN
- BEGIN
- IF Y1>Y2 THEN
- ASM
- MOV AX,Y1
- MOV BX,Y2
- MOV Y1,BX
- MOV Y2,AX
- MOV AX,X1
- MOV BX,X2
- MOV X1,BX
- MOV X2,AX
- END;
- IF (X2>X1) THEN Xi:=1 ELSE Xi:=-1;
- Dy:=Y2-Y1; Dx:=ABS(X2-X1); D:=Dx*2-Dy; Ai:=2*(Dx-Dy);
- Bi:=Dx*2; X:=X1; Y:=Y1;
- IF (X>=0) AND (Y>=0) AND (X<=MaxX) AND (Y<=MaxY)
- THEN SetPix(X,Y,Col);
- FOR Y:=Y1+1 TO Y2 DO
- BEGIN
- IF (D>=0) THEN
- ASM
- MOV AX,X
- ADD AX,Xi
- MOV X,AX
- MOV AX,D
- ADD AX,Ai
- MOV D,AX
- END ELSE ASM
- MOV AX,D
- ADD AX,Bi
- MOV D,AX
- END;
- IF (X>=0) AND (Y>=0) AND (X<=MaxX) AND (Y<=MaxY)
- THEN SetPix(X,Y,Col);
- END;
- END ELSE BEGIN
- IF (X1>X2) THEN
- ASM
- MOV AX,X1
- MOV BX,X2
- MOV X1,BX
- MOV X2,AX
- MOV AX,Y1
- MOV BX,Y2
- MOV Y1,BX
- MOV Y2,AX
- END;
- IF (Y2>Y1) THEN Yi:=1 ELSE Yi:=-1;
- Dx:=X2-X1; Dy:=ABS(Y2-Y1); D:=Dy*2-Dx; Ai:=2*(Dy-Dx);
- Bi:=Dy*2; X:=X1; Y:=Y1;
- IF (X>=0) AND (Y>=0) AND (X<=MaxX) AND (Y<=MaxY)
- THEN SetPix(X,Y,Col);
- FOR X:=X1+1 TO X2 DO
- BEGIN
- IF (D>=0) THEN
- ASM
- MOV AX,Y
- ADD AX,Yi
- MOV Y,AX
- MOV AX,D
- ADD AX,Ai
- MOV D,AX
- END ELSE ASM
- MOV AX,D
- ADD AX,Bi
- MOV D,AX
- END;
- IF (X>=0) AND (Y>=0) AND (X<=MaxX) AND (Y<=MaxY)
- THEN SetPix(X,Y,Col);
- END;
- END;
- END;
-
- {***************************************************************************}
-
- {$L Romans.Obj} PROCEDURE RomansFont; EXTERNAL;
-
- VAR Fs,Fo:WORD;
-
- FUNCTION UseFont(Ptr:POINTER):POINTER;
- BEGIN
- Fs:=SEG(Ptr^); Fo:=OFS(Ptr^)+1; Fh:=MEM[Fs:Fo-1];
- UseFont:=System.Ptr(Fs,Fo);
- END;
-
- PROCEDURE PlotChar(X,Y:INTEGER; Ch:BYTE; Color,Bg:BYTE);
- VAR T,U:BYTE;
- BEGIN
- IF (X<0) OR (Y<0) OR (X>MaxX-8) OR (Y>MaxY-Fh) THEN Exit;
- FOR T:=0 TO 7 DO FOR U:=0 TO Fh-1 DO
- IF MEM[Fs:Fo+Ch*Fh+U] AND (128 SHR (T AND 7))=(128 SHR (T AND 7))
- THEN SetPix(X+T,Y+U,Color) ELSE SetPix(X+T,Y+U,Bg);
- END;
-
- PROCEDURE DrawChar(X,Y:INTEGER; Ch:BYTE; Color:BYTE);
- VAR T,U:BYTE;
- BEGIN
- IF (X<0) OR (Y<0) OR (X>MaxX-8) OR (Y>MaxY-Fh) THEN Exit;
- FOR T:=0 TO 7 DO FOR U:=0 TO Fh-1 DO
- IF MEM[Fs:Fo+Ch*Fh+U] AND (128 SHR (T AND 7))=(128 SHR (T AND 7))
- THEN SetPix(X+T,Y+U,Color);
- END;
-
- PROCEDURE WriteLine(X,Y:INTEGER; S:STRING; C,B:BYTE);
- VAR T:BYTE;
- BEGIN
- FOR T:=1 TO LENGTH(S) DO
- IF C=B THEN DrawChar(X+(T-1)*8,Y,ORD(S[T]),C )
- ELSE PlotChar(X+(T-1)*8,Y,ORD(S[T]),C,B);
- END;
- {***************************************************************************}
- PROCEDURE Bob.GetFg(X,Y:WORD);
- BEGIN
- FOR A:=0 TO Xl DO FOR B:=0 TO Yl DO Fg[A,B]:=GetPix(X+A,Y+B);
- END;
-
- PROCEDURE Bob.SetFg(X,Y:WORD);
- BEGIN
- FOR A:=0 TO Xl DO FOR B:=0 TO Yl DO IF Fg[A,B]<>Bc THEN SetPix(X+A,Y+B,Fg[A,B]);
- END;
-
- PROCEDURE Bob.GetBg(X,Y:WORD);
- BEGIN
- FOR A:=0 TO Xl DO FOR B:=0 TO Yl DO Bg[A,B]:=GetPix(X+A,Y+B);
- END;
-
- PROCEDURE Bob.SetBg(X,Y:WORD);
- BEGIN
- FOR A:=0 TO Xl DO FOR B:=0 TO Yl DO SetPix(X+A,Y+B,Bg[A,B]);
- END;
-
-
- BEGIN
- ASM
- MOV DX,CrtCnf { Enable 2 pages and Graphics }
- MOV AL,00000011b
- OUT DX,AX
- END;
- UseFont(@RomansFont);
- END.